﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel;
using Passwords.Models;
using System.Collections.ObjectModel;

namespace Passwords.Services
{
    public enum BackupState
    {
        Empty,
        Uploading,
        Uploaded,
        Deleted,
        Saving,
        Saved
    }

    [DataContract(Namespace = "http://schemas.datacontract.org/2004/07/PasswordsService")]
    public class Backup : INotifyPropertyChanged
    {
        #region fields

        [DataMember(Name = "Name")]
        private string name;

        [DataMember(Name = "DeviceId")]
        private Guid deviceId;

        [DataMember(Name = "Id")]
        private Guid id;

        [DataMember(Name = "State")]
        private BackupState state;

        [DataMember(Name = "DateCreated")]
        private DateTime dateCreated;

        [DataMember(Name = "Passwords")]
        private ObservableCollection<PasswordContract> passwords;


        [DataMember(Name = "PasswordHash")]
        private byte[] passwordHash;
        private static readonly string formatString = "{2}\n{0} passwords and {1} categories";

        #endregion
        #region ctor

        public Backup()
            : base()
        {
            //passwords = new ObservableCollection<PasswordContract>();
            //Categories = new ObservableCollection<CategoryContract>();
        }

        #endregion
        #region props

        /// <summary>
        /// Helper variable to determine whether to open a backup temorarily, or restore it.
        /// </summary>
        [IgnoreDataMember]
        public bool Restore { get; set; }

        [IgnoreDataMember]
        public string Text
        {
            get
            {

                return string.Format(formatString, PasswordCount, CategoryCount, dateCreated, state.ToString());
            }

        }


        [DataMember]
        public string Info { get; set; }

        [DataMember]
        public bool IsImported { get; set; }

        public byte[] PasswordHash
        {
            get { return passwordHash; }
            set { passwordHash = value; }
        }

        public string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        [IgnoreDataMember]
        public bool IsUploading
        {
            get { return State == BackupState.Uploading; }
        }

        public Guid DeviceId
        {
            get { return deviceId; }
            set { deviceId = value; }
        }

        public Guid Id
        {
            get { return id; }
            set { id = value; }
        }

        public BackupState State
        {
            get { return state; }
            set
            {
                if (value != state)
                {
                    state = value;
                    OnPropertyChanged("State");
                    OnPropertyChanged("IsUploading");
                    OnPropertyChanged("Text");
                }
            }
        }

        public DateTime DateCreated
        {
            get { return dateCreated; }
            set
            {
                if (dateCreated != value)
                {
                    dateCreated = value;
                    OnPropertyChanged("DateCreated");
                }
            }
        }

        [DataMember]
        public ObservableCollection<CategoryContract> Categories { get; set; }

        public ObservableCollection<PasswordContract> Passwords { get { return passwords; } set { passwords = value; } }

        [IgnoreDataMember]
        public int PasswordCount { get { return passwords != null ? passwords.Count : 0; } }

        [IgnoreDataMember]
        public int CategoryCount { get { return Categories != null ? Categories.Count : 0; } }


        #endregion
        #region methods

        public void DeletePassword(PasswordContract password)
        {
            PasswordContract find = Passwords.Where(p => p.Guid == password.Guid).FirstOrDefault();
            if (find != null)
            {
                Passwords.Remove(find);
                OnPropertyChanged("PasswordCount");
            }
        }

        protected void OnPropertyChanged(string propName)
        {
            var eh = PropertyChanged;
            if (eh != null) eh(this, new PropertyChangedEventArgs(propName));
        }

        public void AddPassword(PasswordContract password)
        {
            Passwords.Add(password);
            OnPropertyChanged("PasswordCount");
            OnPropertyChanged("Text");
        }

        public void AddCategory(CategoryContract category)
        {
            Categories.Add(category);
            OnPropertyChanged("CategoryCount");
            OnPropertyChanged("Text");
        }

        #endregion
        #region events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
